package com.kynnnn.cloud.mybatis_interceptor.interceptor;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.kynnnn.cloud.mybatis_interceptor.annotation.EncryptDecryptClass;
import com.kynnnn.cloud.mybatis_interceptor.util.EncryptDecryptUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.sql.Statement;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Properties;

/**
 * <h1>结果集拦截器</h1>
 *
 * @author Zhudiwei
 * @Description TODO
 * @createTime 2021年09月04日
 */
@Component
@Slf4j
@Intercepts({
        @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = Statement.class),
})
public class ResultInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {

        log.debug(">>>>> 进入返回结果拦截器的拦截方法 <<<<<");

        Object result = invocation.proceed();
        if (Objects.isNull(result)) {
            return null;
        }

        if (result instanceof ArrayList) {
            ArrayList resultList = (ArrayList) result;
            if (CollectionUtils.isNotEmpty(resultList) && needToDecrypt(resultList.get(0))) {
                resultList.stream().forEach(item -> EncryptDecryptUtils.decrypt(item));
            }
        } else {
            if (needToDecrypt(result)) {
                EncryptDecryptUtils.decrypt(result);
            }
        }

        return result;
    }

    private boolean needToDecrypt(Object object) {
        Class<?> objectClass = object.getClass();
        EncryptDecryptClass encryptDecryptClass = AnnotationUtils.findAnnotation(objectClass, EncryptDecryptClass.class);
        return Objects.nonNull(encryptDecryptClass);
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}
